嗨嗨!大家好!歡迎來到 Rust 三十天挑戰的第三天!
經過前兩天的基礎洗禮,相信大家對 Rust 的變數和型別系統已經有了初步的認識。今天我們要來學習如何讓程式更有組織性和邏輯性—那就是函式(Functions)和流程控制(Control Flow)!
老實說,剛開始學 Rust 的函式時,我最驚訝的是它對「表達式」和「陳述句」的區分非常嚴格。這在其他語言中可能不是什麼大事,但在 Rust 中卻是非常重要的概念。比如說,if
在 Rust 中不只是條件判斷,它還可以回傳值!這種設計讓程式碼變得更簡潔,但一開始可能會讓人有點不習慣。
不過別擔心,等你理解了這個概念,你會發現 Rust 的表達式系統其實非常優雅和強大!
在 Rust 中,我們使用 fn
關鍵字來定義函式:
fn main() {
println!("Hello from main!");
greet();
say_hello("小明");
}
fn greet() {
println!("哈囉!歡迎來到 Rust 的世界!");
}
fn say_hello(name: &str) {
println!("你好,{}!", name);
}
Rust 的函式參數必須明確指定型別:
fn add_numbers(x: i32, y: i32) {
let result = x + y;
println!("{} + {} = {}", x, y, result);
}
fn calculate_area(width: f64, height: f64) {
let area = width * height;
println!("長方形面積:{:.2} 平方公分", area);
}
fn main() {
add_numbers(5, 3);
calculate_area(10.5, 8.2);
}
這裡來了!Rust 中函式回傳值的語法可能會讓你覺得有點特別:
fn add(x: i32, y: i32) -> i32 {
x + y // 注意:沒有分號!
}
fn multiply(x: i32, y: i32) -> i32 {
return x * y; // 也可以明確使用 return
}
fn get_lucky_number() -> i32 {
42 // 最後一個表達式會被當作回傳值
}
fn main() {
let sum = add(5, 3);
let product = multiply(4, 6);
let lucky = get_lucky_number();
println!("加法:{},乘法:{},幸運數字:{}", sum, product, lucky);
}
重要概念:在 Rust 中,函式的最後一個表達式(沒有分號的那行)會自動成為回傳值。
這是理解 Rust 的重要概念:
fn main() {
let x = 5; // 這是陳述句
let y = {
let inner = 3;
inner + 1 // 這是表達式,沒有分號
}; // 整個區塊是表達式
println!("x = {}, y = {}", x, y); // y 的值是 4
}
if
表達式沒錯,在 Rust 中 if
是表達式,可以回傳值!
fn main() {
let number = 6;
// 傳統的 if 用法
if number % 4 == 0 {
println!("數字可以被 4 整除");
} else if number % 3 == 0 {
println!("數字可以被 3 整除");
} else if number % 2 == 0 {
println!("數字可以被 2 整除");
} else {
println!("數字不能被 4、3 或 2 整除");
}
// if 作為表達式回傳值
let message = if number % 2 == 0 {
"偶數"
} else {
"奇數"
};
println!("{} 是 {}", number, message);
}
loop
、while
、for
loop
:無限迴圈fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // loop 也可以回傳值!
}
};
println!("結果:{}", result); // 輸出:結果:20
}
while
:條件迴圈fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("發射!");
}
for
:迭代迴圈fn main() {
// 迭代陣列
let animals = ["狗", "貓", "兔子", "鳥"];
for animal in animals {
println!("我喜歡{}", animal);
}
// 迭代範圍
println!("\n倒數:");
for number in (1..4).rev() {
println!("{}!", number);
}
println!("發射!🚀");
// 使用索引
println!("\n帶索引的迴圈:");
for (index, animal) in animals.iter().enumerate() {
println!("第 {} 個動物是 {}", index + 1, animal);
}
}
當你有巢狀迴圈時,可以使用標籤來控制要中斷哪一層:
fn main() {
'outer: loop {
println!("進入外層迴圈");
loop {
println!("進入內層迴圈");
break 'outer; // 直接中斷外層迴圈
}
println!("這行永遠不會執行");
}
println!("外層迴圈結束");
}
讓我們用今天學到的知識來建立一個更有組織的程式,完成前兩天的小挑戰:這個程式展示了今天學到的許多重要概念:
1. 函式的組織:
2. 流程控制的應用:
loop
來處理輸入驗證for
迴圈遍歷陣列match
表達式處理不同情況if/else
表達式回傳值3. 表達式的妙用:
match
根據偶數數量回傳不同訊息if/else
鏈來分類數字match
表達式雖然我們還沒正式介紹 match
,但它實在太好用了,讓我簡單展示一下:
fn describe_number(n: i32) -> &'static str {
match n {
0 => "零",
1..=5 => "小數字",
6..=10 => "中等數字",
11..=100 => "大數字",
_ => "超大數字",
}
}
fn get_grade(score: u8) -> char {
match score {
90..=100 => 'A',
80..=89 => 'B',
70..=79 => 'C',
60..=69 => 'D',
_ => 'F',
}
}
fn main() {
println!("7 是 {}", describe_number(7));
println!("95 分的等第是 {}", get_grade(95));
}
💡 補充說明:在此稍微小說明一下,有關於
&'static str
這個使用方法其實是有那麼一點點點小超綱XD
在之後會有一天專門說明他概念的!大家不用擔心!!
今天我們學到了:
函式:
fn
定義函式return
流程控制:
if/else
是表達式,可以回傳值loop
、while
、for
三種迴圈break
和 continue
控制迴圈流程表達式 vs 陳述句:
實用技巧:
明天我們將進入 Rust 最核心也最獨特的概念—所有權系統。這是 Rust 能夠同時保證記憶體安全和高效能的秘密武器。雖然一開始可能會覺得有點抽象,但它絕對是值得深入理解的概念!
試著建立一個簡單的計算機程式,要求:
提示:
match
表達式處理選單選擇如果遇到任何問題,歡迎在留言區討論。函式和流程控制是程式設計的基礎,掌握它們會讓你在後續的學習中更加順利!
我們明天見!